package virtualstock.request;

import javax.ejb.EJBException;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import virtualstock.entity.Game;
import virtualstock.entity.Player;
import virtualstock.entity.Portfolio;
import virtualstock.exception.GameNotFoundException;
import virtualstock.exception.InvalidParameterException;
import virtualstock.exception.PlayerNotFoundException;
import virtualstock.exception.PortfolioNotFoundException;
import virtualstock.util.PortfolioDetails;

/**
 * Session Bean implementation class PortfolioControllerBean
 */
@Stateful
public class PortfolioControllerBean implements PortfolioController {
	@PersistenceContext
	private EntityManager em;
	private Long portfolioID = null;

    /**
     * Default constructor. 
     */
    public PortfolioControllerBean() {
        // TODO Auto-generated constructor stub
    }

	@Override
	public Long createPortfolio(PortfolioDetails details)
			throws InvalidParameterException, GameNotFoundException, PlayerNotFoundException {
		// makes a new portfolio and enters it into db
		Portfolio portfolio = null;
		Game game = null;
		Player player = null;
		
		if (details.getGameID() == null) {
			System.err.println("InvalidParameterException: null gameID");
			throw new InvalidParameterException("null gameID");
		}
		if (details.getPlayerID() == null) {
			System.err.println("InvalidParameterException: null playerID");
			throw new InvalidParameterException("null playerID");
		}
		if (details.getBalance() == null) {
			System.err.println("InvalidParameterException: null balance");
			throw new InvalidParameterException("null balance");
		}
		
		try {
			game = em.find(Game.class, details.getGameID());
		} catch (Exception ex) {
			System.err.println("GameNotFoundException: " + details.getGameID());
			throw new GameNotFoundException(details.getGameID());
		}
		
		try {
			player = em.find(Player.class, details.getPlayerID());
		} catch (Exception ex) {
			System.err.println("PlayerNotFoundException: " + details.getPlayerID());
			throw new PlayerNotFoundException(details.getPlayerID());
		}
		
		try {
			portfolio = new Portfolio(
					details.getGameID(), 
					details.getPlayerID(), 
					details.getBalance());
			em.persist(portfolio);
		} catch (Exception ex) {
			System.err.println("EJBException in createPortfolio: " + ex.getMessage());
			throw new EJBException("createPortfolio: " + ex.getMessage());
		}
		
		return portfolio.getPortfolioID();
	}

	@Override
	public PortfolioDetails getPortfolioDetails(Long portfolioID)
			throws InvalidParameterException, PortfolioNotFoundException {
		// returns the PortfolioDetails for the specified portfolio
		PortfolioDetails details = null;
		
		if (portfolioID == null) {
			System.err.println("InvalidParameterException: null portfolioID");
			throw new InvalidParameterException("null portfolioID");
		}
		
		try {
			Portfolio portfolio = em.find(Portfolio.class, portfolioID);
			
			if (portfolio == null) {
				System.err.println("PortfolioNotFoundException: " + portfolioID);
				throw new PortfolioNotFoundException(portfolioID);
			}
			else {
				details = new PortfolioDetails(
						portfolio.getPortfolioID(), 
						portfolio.getGameID(), 
						portfolio.getPlayerID(), 
						portfolio.getBalance());
			}
		} catch (Exception ex) {
			System.err.println("PortfolioControllerBean.getPortfolioDetails: Caught an exception.");
			ex.printStackTrace();
		}
		
		return details;
	}

	@Override
	public void removePortfolio(Long portfolioID)
			throws InvalidParameterException, PortfolioNotFoundException {
		// removes portfolio from db
		if (portfolioID == null) {
			System.err.println("InvalidParameterException: null portfolioID");
			throw new InvalidParameterException("null portfolioID");
		}
		
		try {
			Portfolio portfolio = em.find(Portfolio.class, portfolioID);
			
			if (portfolio == null) {
				System.err.println("PortfolioNotFoundException: " + portfolioID);
				throw new PortfolioNotFoundException();
			}
			else {
				em.remove(portfolio);
			}
		} catch (Exception ex) {
			System.err.println("EJBException in removePortfolio: " + ex.getMessage());
			throw new EJBException("removePortfolio: " + ex.getMessage());
		}
		
	}

	@Override
	public PortfolioDetails getPortfolioDetailsByGameAndPlayer(Long gameID, Long playerID)
			throws InvalidParameterException, GameNotFoundException, PlayerNotFoundException, PortfolioNotFoundException {
		// TODO Auto-generated method stub
		PortfolioDetails details = null;
		Portfolio portfolio = null;
		Game game = null;
		Player player = null;
		
		if (gameID == null) {
			System.err.println("InvalidParameterException: null gameID");
			throw new InvalidParameterException("null gameID");
		}
		if (playerID == null) {
			System.err.println("InvalidParameterException: null playerID");
			throw new InvalidParameterException("null playerID");
		}
		
		try {
			game = em.find(Game.class, gameID);
		} catch (Exception ex) {
			System.err.println("GameNotFoundException: " + gameID);
			throw new GameNotFoundException(gameID);
		}
		
		try {
			player = em.find(Player.class, playerID);
		} catch (Exception ex) {
			System.err.println("PlayerNotFoundException: " + playerID);
			throw new PlayerNotFoundException(playerID);
		}
		
		Object portfolioIDObj = em.createNamedQuery("Portfolio.FindByGameAndPlayer")
			.setParameter("gameID", game.getGameID())
			.setParameter("playerID", player.getPlayerID())
			.getSingleResult();
		
		if (portfolioIDObj == null) {
			throw new PortfolioNotFoundException();
		}
		else {
			Long portfolioID = (Long) portfolioIDObj;
			portfolio = em.find(Portfolio.class, portfolioID);
			details = new PortfolioDetails(
					portfolio.getPortfolioID(), 
					portfolio.getGameID(), 
					portfolio.getPlayerID(), 
					portfolio.getBalance());	
		}
		
		return details;
	}

}
